/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.InventoryControl;

import java.util.ArrayList;
import java.util.Collection;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import merlion.scm.icm.session.InventoryControlSessionBeanLocal;
import merlion.scm.rmpm.entity.GoodsReceipt;
import merlion.scm.rmpm.entity.RawMaterialItemLine;
import merlion.scm.rmpm.entity.RawMaterialSalesOrder;
import merlion.scm.rmpm.entity.RawMaterialSupplyInformation;
import merlion.scm.rmpm.entity.Supplier;
import org.primefaces.context.RequestContext;

/**
 *
 * @author Kenn
 */
@ManagedBean(name = "grManagerBean")
@ViewScoped
public class GoodsReceiptManagerBean {

    @EJB
    private InventoryControlSessionBeanLocal  icSessionBean;
    
    private GoodsReceipt gr;
    private RawMaterialItemLine rmil;
    private RawMaterialItemLine rmilBackup;
    private String statusMsg;
    
    //--------------------------------------------------------------------------
    //                              Constructor
    //--------------------------------------------------------------------------   
    public GoodsReceiptManagerBean() {
        
        statusMsg = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("statusMsg");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("statusMsg");
        
        gr = new GoodsReceipt();
        gr.setSupplier(new Supplier());
        gr.getSupplier().setRawMaterialsSupplied(new ArrayList<RawMaterialSupplyInformation>());
        rmil = new RawMaterialItemLine();
        rmilBackup = new RawMaterialItemLine();
    }
    
    @PostConstruct
    public void init(){
        gr.setGoodsReceiptId(icSessionBean.generateGoodsReceiptId());
    }
    
    //--------------------------------------------------------------------------
    //                        Manager Bean Methods
    //--------------------------------------------------------------------------   
    
    public Collection<RawMaterialSalesOrder> getAllSalesOrderWOGoodsReceipt(){
        return icSessionBean.getAllSalesOrderWOGoodsReceipt();
    }
    
    public void setSalesOrder(ActionEvent event){
        gr.setSupplier(gr.getRmso().getSupplier());
    }
    
    public Collection<RawMaterialSupplyInformation> getSupplierRawMaterial() {
        return gr.getSupplier().getRawMaterialsSupplied();
    }

    public void addItemLine(ActionEvent event) {

        // Validate
        RequestContext context = RequestContext.getCurrentInstance();
        boolean valid = true;
        if (rmil.getRawMaterialSupplyInformation() == null || rmil.getRawMaterialSupplyInformation().getRawMaterial().getName().equals("")) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw Material is required", ""));
            valid = false;
        }
        if (rmil.getQty() == 0D) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Quantity cannot be zero", ""));
            valid = false;
        }
//        if (rmil.getQty() % rmil.getRawMaterialSupplyInformation().getRawMaterial().getLotSize() != 0L) {
//            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Quantity must be ordered in lot size", ""));
//            valid = false;
//        }
        ArrayList<RawMaterialItemLine> list = new ArrayList<RawMaterialItemLine>(gr.getItemlines());
        list.remove(rmil);
        boolean materialExist = false;
        for (RawMaterialItemLine r : list) {
            if (rmil.getRawMaterialSupplyInformation().getRawMaterial().equals(r.getRawMaterialSupplyInformation().getRawMaterial())) {
                materialExist = true;
            }
        }
        if (materialExist) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw material is already in order items", ""));
            valid = false;
        }
        context.addCallbackParam("valid", valid);
        if (!valid) {
            return;
        }

        gr.getItemlines().add(rmil);

        rmil = new RawMaterialItemLine();
    }

    public void cancelAddItemLine(ActionEvent event) {
        rmil = new RawMaterialItemLine();
    }

    public void editItemLine(ActionEvent event) {
        rmil = (RawMaterialItemLine) event.getComponent().getAttributes().get("selected");
        rmilBackup = rmil.clone();
    }

    public void updateItemLine(ActionEvent event) {

        RequestContext context = RequestContext.getCurrentInstance();
        boolean valid = true;
        if (rmil.getRawMaterialSupplyInformation() == null || rmil.getRawMaterialSupplyInformation().getRawMaterial().getName().equals("")) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw Material is required", ""));
            valid = false;
        }
        if (rmil.getQty() == 0D) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Quantity cannot be zero", ""));
            valid = false;
        }
        if (rmil.getQty() % rmil.getRawMaterialSupplyInformation().getRawMaterial().getLotSize() != 0L) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Quantity must be ordered in lot size", ""));
            valid = false;
        }
        context.addCallbackParam("valid", valid);
        if (!valid) {
            return;
        }

        rmil = new RawMaterialItemLine();
    }

    public void cancelEditItemLine(ActionEvent event) {
        rmil.setQty(rmilBackup.getQty());
        rmil.setRawMaterialSupplyInformation(rmilBackup.getRawMaterialSupplyInformation());
        rmil.setSubtotalSGD(rmilBackup.getSubtotalSGD());
        rmil.setSubtotalUSD(rmilBackup.getSubtotalUSD());
        rmil = new RawMaterialItemLine();
    }

    public void removeItemLine(ActionEvent event) {
        rmil = (RawMaterialItemLine) event.getComponent().getAttributes().get("selected");
    }

    public void confirmRemoveItemLine(ActionEvent event) {
        gr.getItemlines().remove(rmil);
        rmil = new RawMaterialItemLine();
    }

    public void cancelRemoveItemLine(ActionEvent event) {
        rmil = new RawMaterialItemLine();
    }
    
    public String createGoodsReceipt(){
        
        //Validate
        boolean valid = true;
        if(gr.getRmso()== null){
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Sales Order is required", ""));
            valid = false;  
        }
        if(gr.getItemlines().isEmpty()){
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw Material Items cannot be empty", ""));
            valid = false;  
        }
        if(!valid)
            return null;
        // Perform sales order matching
        if (!icSessionBean.matchGoodsReceiptItems(gr)) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Raw Material Items in Sales Order is different. Please check with supplier on the correct order items and quantities", ""));
            return null;
        }

        
        if(icSessionBean.createGoodsReceipt(gr)){
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("statusMsg","Goods Receipt successfully created. Raw material successfully added to inventory warehouse");
        } else {
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("statusMsg","Failed to add raw material to inventory warehouse. Please try again.");
        }
        
        return "createGoodsReceiptStatus?faces-redirect=true";
    }
    
    //--------------------------------------------------------------------------
    //                          Getter and Setter
    //--------------------------------------------------------------------------

    public RawMaterialItemLine getRmil() {
        return rmil;
    }

    public void setRmil(RawMaterialItemLine rmil) {
        this.rmil = rmil;
    }

    public RawMaterialItemLine getRmilBackup() {
        return rmilBackup;
    }

    public void setRmilBackup(RawMaterialItemLine rmilBackup) {
        this.rmilBackup = rmilBackup;
    }

    public String getStatusMsg() {
        return statusMsg;
    }

    public void setStatusMsg(String statusMsg) {
        this.statusMsg = statusMsg;
    }

    public GoodsReceipt getGr() {
        return gr;
    }

    public void setGr(GoodsReceipt gr) {
        this.gr = gr;
    }
    
}
